﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Transactions;
using System.Web;
using System.Web.Mvc;
using System.Web.Security;
using DotNetOpenAuth.AspNet;
using Microsoft.Web.WebPages.OAuth;
using WebMatrix.WebData;
using OnlineMealOrdering.Filters;
using OnlineMealOrdering.Models;
using OnlineMealOrdering.Extends.Attributes;
using OnlineMealOrdering.Persistence;
using OnlineMealOrdering.Extends;
using OnlineMealOrdering.Common;

namespace OnlineMealOrdering.Controllers
{
    public class AccountController : CustomController
    {
        #region Actions

        public ActionResult Login()
        {
            return View();
        }

        public ActionResult GetValidateCode()
        {
            ValidateCode vCode = new ValidateCode();
            string code = vCode.CreateValidateCode(4);
            TempData["ValidateCode"] = code;
            byte[] bytes = vCode.CreateValidateGraphic(code);
            return File(bytes, @"image/jpeg");
        }

        //[ValidateAntiForgeryToken]
        [HttpPost]
        public ActionResult Login(LoginModel model, string returnUrl = "")
        {
            using (var ctx = new OnlineStoreDomainContext())
            {
                try
                {
                    var code = TempData["ValidateCode"] as string;
                    if (model.ValidateCode != code)
                        return JavaScriptShowMsg("error", "提示", "验证码输入错误", "yzm");
                    OnlineMealOrdering.Common.WebLog<AccountController>.AddLog(model.UserCode + ":" + HttpContext.Request.UserHostAddress);

                    bool loginSuccess = AccountModel.ValidateUser(model.UserCode, model.Password);

                    var user = AccountModel.GetUser(model.UserCode);
                    if (loginSuccess)
                    {
                        SetTicketCookieForLogin(user, model.AutoLogin);
                        if (string.IsNullOrWhiteSpace(returnUrl))
                        {
                            return JavaScript("Index", "Home");
                        }
                        else
                        {
                            Redirect(returnUrl);
                        }
                    }
                    else
                    {
                        return JavaScriptShowMsg("error", "提示", "帐号密码输入错误", "account");
                    }
                }
                catch (Exception ex)
                {
                    return JavaScriptShowMsg("error", "提示", ex.Message, "account");
                }
                return View();

            }
        }



        public ActionResult LogOff()
        {
            FormsAuthentication.SignOut();
            return RedirectToAction("Index", "Home");
        }

        public ActionResult Register()
        {
            var model = new AccountModel();
            ViewData["DeliveryTypeList"] = model.GetQuestion();
            return View();
        }

        [HttpPost]
        public ActionResult Register(AccountModel model)
        {
            using (var ctx = new OnlineStoreDomainContext())
            {
                try
                {
                    if (model.Password != model.ConfirmPassword) return Content("密码和确认密码不一致！");
                    if ((TempData["ValidateCode"] as string) != model.VCode) return Content("验证码错误，请重新输入！");
                    if (AccountModel.IsExistsUser(model.UserCode)) return Content("该用户名已经被注册!");
                    model.AccountType = Domain.EnumAccountType.None;
                    var entity = AccountModel.CreateUser(model.UserCode, model.Name, EncryptHelper.EncryptUserPassword(model.Password), model.Question, model.Answer, model.Area, model.Address);
                    ctx.SubmitChanges();
                    SimulateLogin(model.UserCode, model.Password);
                    return Content("succees");
                }
                catch (Exception ex)
                {
                    return Content(ex.Message);
                }
            }
        }

        public ActionResult IsExistsUserCode(string userCode)
        {
            using (var ctx = new OnlineStoreDomainContext())
            {
                return Content(AccountModel.IsExistsUser(userCode).ToString());
            }
        }

        public ActionResult SaveLongitudeLatitude(decimal longitude, decimal latitude)
        {
            using (var ctx = new OnlineStoreDomainContext())
            {
                AccountModel.SaveLongitudeLatitude(longitude, latitude);
                return Content("succeed");
            }
        }


        #endregion

        #region Helper Methods

        private void SetTicketCookieForLogin(AccountModel user, bool isSaveUser = false)
        {
            int expiredMinutes = Config.UserAuthenticationExpirationMinutes;
            DateTime expiration = DateTime.Now.AddMinutes(expiredMinutes);
            if (isSaveUser)
                expiration.AddDays(30);
            FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(
                1,
                user.UserCode,
                DateTime.Now,
                expiration,
                false,
                user.Name + "," + user.Id
                );
            string hashTicket = FormsAuthentication.Encrypt(ticket);

            HttpCookie userCookie = new HttpCookie(FormsAuthentication.FormsCookieName, hashTicket);
            userCookie.HttpOnly = true;
            userCookie.Secure = FormsAuthentication.RequireSSL;
            userCookie.Domain = FormsAuthentication.CookieDomain;
            userCookie.Path = FormsAuthentication.FormsCookiePath;
            if (expiredMinutes > 0) userCookie.Expires = expiration;

            HttpContext.Response.Cookies.Remove(userCookie.Name);
            HttpContext.Response.Cookies.Add(userCookie);
        }

        void SimulateLogin(string userCode, string pwd, bool IsOAuth2 = false)
        {
            try
            {
                bool loginSuccess = ValidateUser(userCode,pwd,IsOAuth2);
                var user = AccountModel.GetUser(userCode);
                if (loginSuccess)
                {
                    SetTicketCookieForLogin(user);
                }
            }
            catch (Exception ex)
            {
                throw BusinessException.Create(ex.Message);
            }
        }

        bool ValidateUser(string userCode, string pwd, bool IsOAuth2 = false)
        {
            if (IsOAuth2)
                return AccountModel.OAuth2ValidateUser(userCode, pwd);
            return AccountModel.ValidateUser(userCode, pwd);
        }

        public void SimulateOAuthLogin(string openid, string openkey)
        {
            try
            {
                if (string.IsNullOrWhiteSpace(openid))
                    openid = RouteData.Values["openid"].ToString();
                if (string.IsNullOrWhiteSpace(openkey))
                    openkey = RouteData.Values["openkey"].ToString();


                bool loginSuccess = AccountModel.OAuth2ValidateUser(openid, openkey);
                var user = AccountModel.GetUser(openid);
                if (loginSuccess)
                {
                    SetTicketCookieForLogin(user);
                }
            }
            catch (Exception ex)
            {
                throw BusinessException.Create(ex.Message);
            }
        }





        #endregion

    }
}
